package com.example.java_gobang.api;

import com.example.java_gobang.game.MatchRequest;
import com.example.java_gobang.game.MatchResponse;
import com.example.java_gobang.game.Matcher;
import com.example.java_gobang.game.OnlineUserManager;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.PongMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * @author krystal
 * @date 2023/3/12 12:33
 */
//通过这个类来处理匹配功能中的websocket请求
@Component
public class MatchAPI extends TextWebSocketHandler {
        @Autowired
        private ObjectMapper objectMapper=new ObjectMapper();

        @Autowired
        private OnlineUserManager onlineUserManager;

        @Autowired
        private Matcher matcher;

        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            //玩家上线，加入到onlineUserManager中

            //1、先获取到当前用户的身份信息（谁在游戏大厅中，建立的连接）
            //由于在注册webSocket时加上了.addInterceptors(new HttpSessionHandshakeInterceptor()，能够getAttributes()
            //这个逻辑就是把HttpSession中的Attribute拿到WebSocketSession中了
            //在Http登录逻辑中，往HttpSession中存入了User数据，httpsession.setAttribute("user",user)
            //此时就可以在WebSocketSession中把之前HttpSession里存的User对象给拿到了
            try {
                User user=(User) session.getAttributes().get("user");
//                if (user == null) {
//                    // 拿不到用户的登录信息, 说明玩家未登录就进入游戏大厅了.
//                    // 则返回错误信息并关闭连接
//                    MatchResponse response = new MatchResponse();
//                    response.setOk(false);
//                    response.setReason("玩家尚未登录!");
//                    session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
//                    return;
//                }
                //2、先判定当前用户是否已经登录过（是在线状态），如果已经在线，不进行后续逻辑
                if (onlineUserManager.getFromGameHall(user.getUserId())!=null
                    || onlineUserManager.getFromGameRoom(user.getUserId())!=null){
                    //当前已经登录过了，告知客户端重复登录了
                    MatchResponse response=new MatchResponse();
                    response.setOk(true);
                    response.setReason("当前禁止多开！");
                    response.setMessage("repeatConnection");
                    session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                    //session.close();
                    return;
                }

                //3、拿到身份信息之后，就可以把玩家设置为在线状态
                onlineUserManager.enterGameHall(user.getUserId(), session);
                System.out.println("玩家"+user.getUsername()+"进入游戏大厅！");
            }catch (NullPointerException e){
                System.out.println("[MatchAPI.afterConnectionEstablished]当前用户未登录");
                //出现空指针异常，说明当前用户的身份信息为空，用户未登录
                //把当前用户尚未登录这个信息返回回去
                MatchResponse response=new MatchResponse();
                response.setOk(false);
                response.setReason("您尚未登录！不能进行玩家匹配功能！");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            }

        }

        @Override
        protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
            //实现处理开始匹配请求和处理停止匹配请求
            User user=(User) session.getAttributes().get("user");
            //获取到客户端给服务器发送的数据
            String payload=message.getPayload();
            //当前这个数据是一个JSON格式的字符串，需要转成java对象
            MatchRequest request=objectMapper.readValue(payload,MatchRequest.class);
            MatchResponse response=new MatchResponse();
            if (request.getMessage().equals("startMatch")){
                //进入匹配队列
                matcher.add(user);
                //先创建一个类表示匹配队列，把当前用户加进去
                //把玩家信息放入匹配队列之后，就可以返回一个响应给客户端
                response.setOk(true);
                response.setMessage("startMatch");
            }else if (request.getMessage().equals("stopMatch")){
                //退出匹配队列
                matcher.remove(user);
                //先创建一个类表示匹配队列，把当前用户取进去
                //把玩家信息放入匹配队列之后，就可以返回一个响应给客户端
                response.setOk(true);
                response.setMessage("stopMatch");
            }else{
                //非法情况
                response.setOk(false);
                response.setReason("非法的匹配请求");
            }
            String jsonString=objectMapper.writeValueAsString(response);
            session.sendMessage(new TextMessage(jsonString));
        }

        @Override
        public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
            try {
                //玩家下线，退出onlineUserManager
                User user=(User) session.getAttributes().get("user");
                WebSocketSession tmpSession=onlineUserManager.getFromGameHall(user.getUserId());
                if (tmpSession==session){
                    onlineUserManager.exitGameHall(user.getUserId());
                }
                //如果玩家正在匹配中，websocket连接断开了，就应该移除匹配队列
                matcher.remove(user);
            }catch (NullPointerException e){
                System.out.println("[MatchAPI.handleTransportError]当前用户未登录");
//                e.printStackTrace();
//                MatchResponse response=new MatchResponse();
//                response.setOk(false);
//                response.setReason("您尚未登录！不能进行玩家匹配功能！");
//                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            }
        }

        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            try {
                //玩家下线，退出onlineUserManager
                User user=(User) session.getAttributes().get("user");
                WebSocketSession tmpSession=onlineUserManager.getFromGameHall(user.getUserId());
                if (tmpSession==session){
                    onlineUserManager.exitGameHall(user.getUserId());
                }
                //如果玩家正在匹配中，websocket连接断开了，就应该移除匹配队列
                matcher.remove(user);
            }catch (NullPointerException e){
                e.printStackTrace();
                MatchResponse response=new MatchResponse();
                response.setOk(false);
                response.setReason("您尚未登录！不能进行玩家匹配功能！");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            }
        }
}
